/**********************************************************************************
 *
 *	文件名称：ShowBMP.c
 * 	文件作用：输入指定参数将指定JPG图片显示到指定位置
 * 	文件作者：WSY
 * 	修改日期：2023.12.25
 *  注意事项：
 *
 *	版权声明：CopyRight (c)  @cecelmx.126.com  All Right Reserved
 * ********************************************************************************/

#include "showImg.h"
#include "head.h"


int showImgJpg(char *imgPath, int *lcd_mmp, int start_x, int start_y, int mode)
{
  /*
   * 1.新建一个解码对象并初始化
   */
  // 新建对象
  struct jpeg_decompress_struct cinfo;

  // 新建标准错误结构体
  struct jpeg_error_mgr jerr;

  /* 新建文件流 */
  FILE *infile;

  /* 建立缓冲区 */
  unsigned char *buffer;
  int row_stride; /* 存储图像宽度 */

  // 将传入的jpg图片打开
  if ((infile = fopen(imgPath, "rb")) == NULL)
  {
    fprintf(stderr, "can't open %s\n", imgPath);
    return 0;
  }

  /* 2初始化 */
  cinfo.err = jpeg_std_error(&jerr);
  jpeg_create_decompress(&cinfo);

  /* Step 3: 读取图像头信息，存储宽度*/

  jpeg_stdio_src(&cinfo, infile);
  jpeg_read_header(&cinfo, TRUE);

  /*4 设置图片参数，如果是大图则按原图显示，如果是缩略图模式，则缩放至合适大小*/
  /* 设置缩放比例 */
  if (SHOW_MODE_TL == mode)
  {
    /*计算要放大n倍还是缩减n倍*/
    int target_width = 200;                 // 目标宽度
    int original_width = cinfo.image_width; // 获取图片的宽度

    int scale_num, scale_denom; // 缩放比例的分子和分母

    if (original_width < target_width)
    {
      // 如果原始宽度小于目标宽度，放大特定比率
      double ratio = (double)target_width / original_width;
      scale_num = (int)(ratio * 100);
      scale_denom = 100;
    }
    else
    {
      // 如果原始宽度大于等于目标宽度，缩小特定比率
      double ratio = (double)original_width / target_width;
      scale_num = 100;
      scale_denom = (int)(ratio * 100);
    }

    /*将计算好的比率进行设置*/
    cinfo.scale_num = scale_num;
    cinfo.scale_denom = scale_denom;
  }

  /*开始解码*/
  jpeg_start_decompress(&cinfo);

  // 存储图像宽度： 像素 * 色深（字节）
  row_stride = cinfo.output_width * cinfo.output_components;

  // 6循环读取并处理图片颜色分类
  buffer = calloc(1, row_stride); // 申请一行大小的缓冲区
  while (cinfo.output_scanline < cinfo.output_height)
  {
    /* 如果读取的行数小于文件的高，则循环读取一行数据到缓冲区 */
    jpeg_read_scanlines(&cinfo, &buffer, 1);

    /* 如果每一行的图像宽度没有够，则将数据添加到开发板的内存映射里面 */
    for (int i = 0; i < cinfo.output_width; i++)
    {
      *(lcd_mmp + start_y * 800 + start_x + (cinfo.output_scanline - 1) * 800 + i) = (buffer[i * 3] << 16) | (buffer[i * 3 + 1] << 8) | buffer[i * 3 + 2];
    }
  }

  /* Step 7: 完成解码 */

  jpeg_finish_decompress(&cinfo);

  /* Step 8: 释放资源 */

  jpeg_destroy_decompress(&cinfo);

  // 关闭图片
  fclose(infile);

  return 1;
}
